package com.csun.cmny.provider.service.impl;

import com.csun.cmny.base.constant.JiGuangConstant;
import com.csun.cmny.base.dto.LoginAuthDto;
import com.csun.cmny.base.enums.ErrorCodeEnum;
import com.csun.cmny.core.support.BaseService;
import com.csun.cmny.provider.dao.OmcSchedulMapper;
import com.csun.cmny.provider.dao.OmcSchedulMonthMapper;
import com.csun.cmny.provider.exceptions.OmcBizException;
import com.csun.cmny.provider.model.constant.ScheduleConstant;
import com.csun.cmny.provider.model.domain.OmcPlan;
import com.csun.cmny.provider.model.domain.OmcSchedul;
import com.csun.cmny.provider.model.domain.OmcSchedulMonth;
import com.csun.cmny.provider.model.domain.OmcShifts;
import com.csun.cmny.provider.model.dto.SchedulListDto;
import com.csun.cmny.provider.model.dto.SendMessageRequest;
import com.csun.cmny.provider.model.vo.RpcRoleVo;
import com.csun.cmny.provider.model.vo.SchedulListVO;
import com.csun.cmny.provider.model.vo.message.ScheduleVo;
import com.csun.cmny.provider.service.*;
import com.csun.cmny.provider.utils.MenuTimeUtil;
import com.csun.cmny.provider.vo.OmcSchedulMonthVo;
import com.google.common.collect.Lists;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import tk.mybatis.mapper.entity.Example;

import javax.annotation.Resource;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

@Slf4j
@Service
public class OmcScheduleServiceImpl extends BaseService<OmcSchedul> implements OmcScheduleService {

    @Resource
    private OmcSchedulMapper omcSchedulMapper;
    @Resource
    private OmcGroupService omcGroupService;
    @Resource
    private OmcPlanService omcPlanService;
    @Resource
    private UacRpcService uacRpcService;
    @Resource
    private OmcShiftsService omcShiftsService;
    @Resource
    private OpcMessageService opcMessageService;
    @Resource
    private OmcSchedulMonthMapper omcSchedulMonthMapper;

    @Override
    public Integer saveSchedul(SchedulListDto schedulListDto, LoginAuthDto loginAuthDto) {

        //定义班组id
        Integer nursingGroupId = getNursingGroupId(schedulListDto.getNursingGroupId(),loginAuthDto);

        //定义周数
        String week;

        if(schedulListDto.getWeek() == null || schedulListDto.getWeek().equals("")){
            //计算周数
            String date = getDate(schedulListDto.getOmcSchedulList());
            week = MenuTimeUtil.getDays(date).get(1) + MenuTimeUtil.getDays(date).get(0);
        }else{
            week = schedulListDto.getWeek();
        }

        //放入使用者信息
        List<OmcSchedul> omcScheduls = schedulListDto.getOmcSchedulList();
        if(omcScheduls != null && omcScheduls.size() > 0){
            for(OmcSchedul item : omcScheduls){
                //不需要提供id
                item.setId(null);
                item.setUpdateInfo(loginAuthDto);
                item.setNursingGroupId(nursingGroupId);
                item.setGroupId(loginAuthDto.getGroupId());
                item.setWeek(Integer.parseInt(week));
                item.setStatus(0);
            }
        }

        //校验该周计划是否存在
        OmcSchedul querySchedul = new OmcSchedul();
        querySchedul.setNursingGroupId(nursingGroupId);
        querySchedul.setWeek(Integer.valueOf(week));
        List<OmcSchedul> omcSchedulQueryList = omcSchedulMapper.select(querySchedul);

        //生成推送
        SendMessageRequest sendMessageRequest = new SendMessageRequest();
        sendMessageRequest.setMsgCode(ScheduleConstant.Schedule_FLOW_NURSING_ADD);
        sendMessageRequest.setGroupId(loginAuthDto.getGroupId());

        //保存排班计划
        if(omcSchedulQueryList != null && omcSchedulQueryList.size() > 0){
            //当该周该班组排班计划存在时，删除原计划，重新添加
            int retDel = delete(querySchedul);
            int i = batchSave(omcScheduls);
            //推送
            opcMessageService.pushWithMsgCode(sendMessageRequest);
            return i;
        }else{
            //当计划不存在时,计划使用次数+1
            OmcPlan omcPlan = omcPlanService.selectByKey(schedulListDto.getOmcSchedulList().get(0).getPlanId());
            omcPlan.setIsUsed(omcPlan.getIsUsed()+1);
            int ret = omcPlanService.update(omcPlan);
            if(ret < 1){
                throw new OmcBizException(ErrorCodeEnum.OMC10035005);
            }
            //批量添加计划
            int i = batchSave(schedulListDto.getOmcSchedulList());

            //推送
            opcMessageService.pushWithMsgCode(sendMessageRequest);
            return i;
        }
    }

    @Override
    public List<OmcSchedul> queryScheduleList(OmcSchedul schedulQuery, LoginAuthDto loginAuthDto) {

        //查询护工组id
        int nursingGroupId = getNursingGroupId(schedulQuery.getNursingGroupId(),loginAuthDto);
        schedulQuery.setNursingGroupId(nursingGroupId);

        //查询班组计划
        List<OmcSchedul> omcSchedulList = omcSchedulMapper.select(schedulQuery);

        //放入shifts对象
        if(omcSchedulList != null && omcSchedulList.size() > 0){
            omcSchedulList = omcShiftsService.setShiftsOfSchedule(omcSchedulList);
        }

        return omcSchedulList;
    }

    @Override
    public Integer approvalSchedule(SchedulListDto schedulListDto, LoginAuthDto loginAuthDto) {

        List<OmcSchedul> omcSchedulList = schedulListDto.getOmcSchedulList();

        //查询该周交班项，检验审批状态
        OmcSchedul schedulQuery = new OmcSchedul();
        schedulQuery.setWeek(omcSchedulList.get(0).getWeek());
        schedulQuery.setNursingGroupId(schedulListDto.getNursingGroupId());
        List<OmcSchedul> currentSchedulList = select(schedulQuery);

        if(currentSchedulList.size() < 1){
            throw new OmcBizException(ErrorCodeEnum.OMC10036001);
        }

        int currentStatus = currentSchedulList.get(0).getStatus();
        log.info("========= [currentStatus] : " + currentStatus);

        if(currentStatus != 0){
            throw new OmcBizException(ErrorCodeEnum.OMC10036009);
        }

        //获取审批原因
        String reason = schedulListDto.getReason();
        //获取审批状态 1.未通过 2.通过
        Integer status = schedulListDto.getStatus();

        int i = 0;
        for(OmcSchedul item : omcSchedulList){
            OmcSchedul omcSchedul = new OmcSchedul();
            omcSchedul.setStatus(status);
            omcSchedul.setReason(reason);
            omcSchedul.setId(item.getId());
            omcSchedulMapper.updateByPrimaryKeySelective(omcSchedul);
            i++;
        }
        if(omcSchedulList.size() > 0){
            //申请人Id
            Long applyId = selectByKey(omcSchedulList.get(0).getId()).getCreatorId();

            //生成推送
            SendMessageRequest sendMessageRequest = new SendMessageRequest();
            sendMessageRequest.setUserIdList(Lists.newArrayList(applyId));
            sendMessageRequest.setGroupId(loginAuthDto.getGroupId());
            /**
             * @date    2019-12-09
             * @author  chisj
             * @desc    推送描述信息
             */
            sendMessageRequest.setExtrasParam(omcSchedulList.get(0));
            sendMessageRequest.setTagList(Lists.newArrayList(JiGuangConstant.TAG_PREFIX_USER + applyId));
            if(status == 2){
                sendMessageRequest.setMsgCode(ScheduleConstant.Schedule_FLOW_SERVICE_AGREE);
            }else if(status == 1){
                sendMessageRequest.setMsgCode(ScheduleConstant.Schedule_FLOW_SERVICE_REFUSE);
            }
            opcMessageService.pushByUser(sendMessageRequest);
        }
        return i;
    }

    @Override
    public List<OmcSchedul> queryShiftUsers(OmcSchedul omcSchedul, LoginAuthDto loginAuthDto) {

        //查询护工组id
        int nursingGroupId = getNursingGroupId(omcSchedul.getNursingGroupId(),loginAuthDto);

        omcSchedul.setNursingGroupId(nursingGroupId);

        List<OmcSchedul> omcSchedulList = omcSchedulMapper.select(omcSchedul);

        for(OmcSchedul item : omcSchedulList){
            item.setOmcShifts(omcShiftsService.selectByKey(item.getShiftsId()));
        }

        return omcSchedulList;
    }

    @Override
    public int deleteScheadule(OmcSchedul omcSchedul, LoginAuthDto loginAuthDto) {

        int nursingGroupId = getNursingGroupId(omcSchedul.getNursingGroupId(),loginAuthDto);

        omcSchedul.setNursingGroupId(nursingGroupId);

        //获取当日日期
        String thisDate = new SimpleDateFormat("yyyy-MM-dd").format(new Date());
        //获取本周周数
        String thisWeek = MenuTimeUtil.getDays(thisDate).get(1) + MenuTimeUtil.getDays(thisDate).get(0);

        //如果是本周以后的排班计划，可以删除
        if(omcSchedul.getWeek() > Integer.parseInt(thisWeek)) {
            return delete(omcSchedul);
        }else{
            throw new OmcBizException(ErrorCodeEnum.OMC10035009);
        }
    }

    @Override
    public List<ScheduleVo> queryScheduleCurTaskList(String thisWeek,LoginAuthDto loginAuthDto) {

        //查询待审批的排班计划
        Integer queryWeek = Integer.parseInt(thisWeek);
        Example example = new Example(OmcSchedul.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("groupId",loginAuthDto.getGroupId());
        criteria.andEqualTo("status",0);
        criteria.andGreaterThanOrEqualTo("week",queryWeek);
        List<OmcSchedul> schedulList = selectByExample(example);

        Set<Integer> nursingGroupIdSet = schedulList.stream().map(s->s.getNursingGroupId()).collect(Collectors.toSet());
        List<ScheduleVo> voList = Lists.newArrayList();

        for(Integer nursingGroupId : nursingGroupIdSet){
            List<OmcSchedul> schedulsTempByNursingGroupId = Lists.newArrayList();
            for(OmcSchedul schedul : schedulList){
                if(schedul.getNursingGroupId() == nursingGroupId){
                    schedul.setOmcShifts(omcShiftsService.selectByKey(schedul.getShiftsId()));
                    schedulsTempByNursingGroupId.add(schedul);
                }
            }
            Set<Integer> weekSet = schedulsTempByNursingGroupId.stream().map(s->s.getWeek()).collect(Collectors.toSet());
            for(Integer week : weekSet){
                List<OmcSchedul> schedulsTempByWeek = Lists.newArrayList();
                for(OmcSchedul schedul : schedulsTempByNursingGroupId){
                    if(schedul.getWeek().equals(week)){
                        schedulsTempByWeek.add(schedul);
                    }
                }
                ScheduleVo scheduleVo = new ScheduleVo();
                scheduleVo.setSchedulList(schedulsTempByWeek);
                scheduleVo.setNursingGroupId(nursingGroupId);
                scheduleVo.setWeek(week);
                voList.add(scheduleVo);
            }
        }
        return voList;
    }
    /**
     * 查询护工组月计划
     * @param omcSchedulMonthVo
     * @return Wrapper
     * @author HD
     * @date  14:04
     */
    @Override
    public List<OmcSchedulMonth> queryScheduleMonthList(OmcSchedulMonthVo omcSchedulMonthVo, LoginAuthDto loginAuthDto) {
        OmcSchedulMonth omcSchedulMonth = new OmcSchedulMonth();
        omcSchedulMonth.setNursingGroupId(omcSchedulMonthVo.getNursingGroupId());
        omcSchedulMonth.setGroupId(loginAuthDto.getGroupId());
        omcSchedulMonth.setMonth(omcSchedulMonthVo.getMonth());
        List<OmcSchedulMonth> select = omcSchedulMonthMapper.select(omcSchedulMonth);
        if(select.size() > 0){
            OmcShifts omcShifts = new OmcShifts();
            omcShifts.setPlanid(omcSchedulMonthVo.getPlanId());
            List<OmcShifts> omcShift = omcShiftsService.select(omcShifts);
            select.get(0).setOmcShifts(omcShift.get(0));
        }
        return select;
    }

    public int getNursingGroupId(Integer omcNurisngGroupId,LoginAuthDto loginAuthDto){

        //查询用户身份
        List<RpcRoleVo> rpcRoleVos = uacRpcService.queryRoleListByUserId(loginAuthDto.getUserId());

        //定义班组id
        Integer nursingGroupId = 0;

        for(RpcRoleVo vo : rpcRoleVos){
            //1.身份为护工时，班组id为护工所在的班组id
            if(vo.getRoleCode().equals("nursing")){
                nursingGroupId = omcGroupService.selectNuringGroupIdByUserId(loginAuthDto.getUserId()).intValue();
                //2.身份为服务部长时，班组id为服务部长指定的id
            }else {
                nursingGroupId = omcNurisngGroupId;
            }
        }
        if( nursingGroupId == null){
            throw new OmcBizException(ErrorCodeEnum.OMC10035006);
        }

        return nursingGroupId;

    }

    public String getDate(List<OmcSchedul> schedulList){

        String date = new String();

        //获取一个不为空的日期
        for( int i = 0,j = schedulList.size(); i < j; i++ ){
            if(schedulList.get(i).getMonDate() != null && schedulList.get(i).getMonDate() != ""){
                date = schedulList.get(i).getMonDate();
                break;
            }
            if(schedulList.get(i).getTueDate() != null && schedulList.get(i).getTueDate() != ""){
                date = schedulList.get(i).getTueDate();
                break;
            }
            if(schedulList.get(i).getWedDate() != null && schedulList.get(i).getWedDate() != ""){
                date = schedulList.get(i).getWedDate();
                break;
            }
            if(schedulList.get(i).getThuDate() != null && schedulList.get(i).getThuDate() != ""){
                date = schedulList.get(i).getThuDate();
                break;
            }
            if(schedulList.get(i).getFriDate() != null && schedulList.get(i).getFriDate() != ""){
                date = schedulList.get(i).getFriDate();
                break;
            }
            if(schedulList.get(i).getSatDate() != null && schedulList.get(i).getSatDate() != ""){
                date = schedulList.get(i).getSatDate();
                break;
            }
            if(schedulList.get(i).getSunDate() != null && schedulList.get(i).getSunDate() != ""){
                date = schedulList.get(i).getSunDate();
                break;
            }
        }
        if(date.equals(null) || date.equals("")){
            throw new OmcBizException(ErrorCodeEnum.OMC10036005);
        }
        return date;
    }

}
